;;
;; Copyright (c) 2010, Justin Grant <justin at imagine27 dot com>
;; All rights reserved.

;; Redistribution and use in source and binary forms, with or without modification
;; are permitted provided that the following conditions are met:

;; Redistributions of source code must retain the above copyright notice, this list
;; of conditions and the following disclaimer.
;; Redistributions in binary form must reproduce the above copyright notice, this
;; list of conditions and the following disclaimer in the documentation and/or
;; other materials provided with the distribution.
;; Neither the name of the <ORGANIZATION> nor the names of its contributors may be
;; used to endorse or promote products derived from this software without specific
;; prior written permission.
;;
;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
;; ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
;; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
;; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE
;; EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;;

(set! *warn-on-reflection* true)

(ns clijx.core
  (:import [java.awt Color Toolkit Font GraphicsEnvironment Graphics2D Graphics]
           [java.awt.image BufferStrategy]
           [java.awt.event ActionListener MouseMotionListener KeyListener
            MouseEvent KeyEvent]
           [javax.swing JFrame Timer WindowConstants])
  (:use [clijx.data]
        [clijx.math])
  (:gen-class))


(defn stop-game [g]
  (swap! g assoc :started false)
  (.stop ^Timer (@g :timer)))

(defn start-game [g]
  (swap! g assoc :started true)
  (.start ^Timer (@g :timer)))

(defn reset-game [g]
  (when (:timer @g) (stop-game g))
  (reset-game-data g))

(defn game-frame [game player1 f1 f2]
  (proxy [JFrame ActionListener KeyListener] []
    (paint [^Graphics gr]
      (let [^JFrame this this
            ^Graphics2D gr gr
            ;; ^BufferStrategy bs (.getBufferStrategy this)
            ;; ^Graphics2D gr2d (when bs (.getDrawGraphics bs))
            ]
        ;; (.setColor gr2d Color/RED)
        ;; (.fillRect gr2d 0 0 (@game :display-width) (@game :display-height))
        ;; (.setColor gr2d Color/WHITE)
        ;; (.setFont gr2d f1)
        ;; (.drawString gr2d (str "CLIJX") 20 35)
        ;; (.dispose gr2d)
        ;; (.show bs)
        (.setColor gr Color/BLACK)
        (.fillRect gr 0 0 (@game :display-width) (@game :display-height))
        (.setColor gr Color/WHITE)
        (.setFont gr f1)
        (.drawString gr (str "CLIJX") 20 35)
        ))

    (keyPressed [#^KeyEvent e]
      ;; start game
      (when (and (not (:started @game)) (= (.getKeyChar e) \s))
        (reset-game game)
        (start-game game))
      ;; quit game
      (when (= (.getKeyChar e) \q)
        (reset-game game)
        (.dispose ^JFrame this))
      ;; pause game
      (when (= (.getKeyChar e) \p)
        (if (:paused @game)
          (.start ^Timer (:timer @game))
          (.stop ^Timer (:timer @game)))
        (swap! game assoc :paused
               (not (:paused @game))))
      ;; movement
      (when (= (.getKeyCode e) KeyEvent/VK_LEFT)
        (swap! player1 assoc :prev-dir (:dir @player1))
        (swap! player1 assoc :dir :west))
      (when (= (.getKeyCode e) KeyEvent/VK_RIGHT)
        (swap! player1 assoc :prev-dir (:dir @player1))
        (swap! player1 assoc :dir :east))
      (when (= (.getKeyCode e) KeyEvent/VK_UP)
        (swap! player1 assoc :prev-dir (:dir @player1))
        (swap! player1 assoc :dir :north))
      (when (= (.getKeyCode e) KeyEvent/VK_DOWN)
        (swap! player1 assoc :prev-dir (:dir @player1))
        (swap! player1 assoc :dir :south)))

    (keyReleased [e])

    (keyTyped [e])

    (actionPerformed [e]
      (println (:dir @player1))
      (let [#^JFrame this this]
        (.repaint this)))))


(defn -main []
  (let [tk (Toolkit/getDefaultToolkit)
        ge (GraphicsEnvironment/getLocalGraphicsEnvironment)
        gd (.getDefaultScreenDevice ge)
        ;;game (new-game (.. tk getScreenSize height)
        ;;                  (.. tk getScreenSize width))
        #^JFrame screen (game-frame
                         game player1
                         (Font. "Courier New" Font/BOLD 14)
                         (Font. "Courier New" Font/BOLD 24))]
    (reset-game game)
    (swap! game assoc :timer (Timer. 20 screen))
    (.setDefaultCloseOperation screen WindowConstants/DISPOSE_ON_CLOSE)
    (.setSize screen (@game :display-width) (@game :display-height))
    (doto screen
      (.setResizable false)
      (.setBackground Color/BLACK)
      ;;(.setIgnoreRepaint true)
      (.addKeyListener screen))
    ;;(when (not (. screen isDisplayable)) (.setUndecorated screen true))
    (.setVisible screen true)
    ;; (.setFullScreenWindow gd screen)
    ;; (.createBufferStrategy screen 2)
    (.toFront screen)
    ))

